package com.pactera.madp.cp.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pactera.madp.common.core.exception.CheckedException;
import com.pactera.madp.common.core.util.R;
import com.pactera.madp.common.data.tenant.TenantContextHolder;
import com.pactera.madp.cp.api.dto.product.ProductGroupAddDto;
import com.pactera.madp.cp.api.dto.product.ProductGroupUpdateDto;
import com.pactera.madp.cp.api.entity.BaseEntity;
import com.pactera.madp.cp.api.entity.WorkEmployeeDepartmentEntity;
import com.pactera.madp.cp.api.entity.WorkEmployeeEntity;
import com.pactera.madp.cp.api.entity.product.*;
import com.pactera.madp.cp.api.vo.product.ProductGroupVO;
import com.pactera.madp.cp.common.constant.Constant;
import com.pactera.madp.cp.handler.CorpContextHolder;
import com.pactera.madp.cp.mapper.product.ProductGroupMapper;
import com.pactera.madp.cp.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 产品分类服务实现类
 *
 * @author kedongZhang
 * @date 2021/5/26 10:49
 */
@Service
public class ProductGroupServiceImpl extends ServiceImpl<ProductGroupMapper,ProductGroupEntity> implements ProductGroupService {

    @Autowired
    IWorkDeptService workDeptService;
    @Autowired
    ProductService productService;
    @Autowired
    ProductGroupDepartmentService productGroupDepartmentService;
    @Autowired
    IWorkEmployeeDepartmentService workEmployeeDepartmentService;
    @Autowired
    IWorkEmployeeService workEmployeeService;
    @Autowired
    private ProdEmployeeService prodEmployeeService;
    @Resource
    private ProdEmployeeGroupService prodEmployeeGroupService;

    /**
     * 新建分类
     *
     * @param productGroupAddDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveGroup(ProductGroupAddDto productGroupAddDto) {
        Integer corpId = CorpContextHolder.getCorpId();
        ProductGroupEntity productGroupEntity = new ProductGroupEntity();
        BeanUtil.copyProperties(productGroupAddDto,productGroupEntity);
        productGroupEntity.setCreateTime(LocalDateTime.now());
        productGroupEntity.setCorpId(corpId);
        productGroupEntity.setTenantId(TenantContextHolder.getTenantId());
        baseMapper.insert(productGroupEntity);
        //若可视范围为：可用部门，则保存产品分类和部门关系
        if (Constant.VISIBLE_RANGE_2.equals(productGroupAddDto.getVisibleRange())) {
            if (!productGroupAddDto.getDeptList().isEmpty()) {
                List<ProductGroupDepartmentEntity> productGroupDepartmentEntityList = new ArrayList();
                for (Integer deptId : productGroupAddDto.getDeptList()) {
                    ProductGroupDepartmentEntity productGroupDepartmentEntity = new ProductGroupDepartmentEntity();
                    productGroupDepartmentEntity.setGroupId(productGroupEntity.getId());
                    productGroupDepartmentEntity.setDeptId(deptId);
                    productGroupDepartmentEntityList.add(productGroupDepartmentEntity);
                }
                productGroupDepartmentService.saveBatch(productGroupDepartmentEntityList);
            }
        }
        return true;
    }

    /**
     * 编辑分类
     *
     * @param productGroupUpdateDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R updateGroup(ProductGroupUpdateDto productGroupUpdateDto) {

        ProductGroupEntity productGroupEntity = this.getById(productGroupUpdateDto.getId());
        if (productGroupEntity.getName().equals("精选")) {
            return R.failed(Boolean.FALSE,"精选不能编辑");
        }
        //校验名称是否重复
        ProductGroupEntity groupEntity = this.getOne(Wrappers.<ProductGroupEntity>query().lambda()
                .eq(ProductGroupEntity::getName,productGroupUpdateDto.getName())
                .ne(ProductGroupEntity::getId,productGroupUpdateDto.getId()));
        if (groupEntity != null) {
            return R.failed(Boolean.FALSE,"修改失败,分类名称已存在");
        }

        ProductGroupEntity productGroup = new ProductGroupEntity();
        BeanUtils.copyProperties(productGroupUpdateDto,productGroup);
        productGroup.setUpdateTime(LocalDateTime.now());
        baseMapper.updateById(productGroup);
        //清掉更新前产品分类与部门的关系
        productGroupDepartmentService.remove(Wrappers.<ProductGroupDepartmentEntity>query().lambda()
                .eq(ProductGroupDepartmentEntity::getGroupId,productGroupUpdateDto.getId()));
        //若可视范围为：可用部门，则保存产品分类和部门关系
        if (Constant.VISIBLE_RANGE_2.equals(productGroupUpdateDto.getVisibleRange())) {
            if (!productGroupUpdateDto.getDeptList().isEmpty()) {
                List<ProductGroupDepartmentEntity> productGroupDepartmentEntityList = new ArrayList();
                for (Integer deptId : productGroupUpdateDto.getDeptList()) {
                    ProductGroupDepartmentEntity productGroupDepartmentEntity = new ProductGroupDepartmentEntity();
                    productGroupDepartmentEntity.setGroupId(productGroup.getId());
                    productGroupDepartmentEntity.setDeptId(deptId);
                    productGroupDepartmentEntityList.add(productGroupDepartmentEntity);
                }
                return R.ok(productGroupDepartmentService.saveBatch(productGroupDepartmentEntityList));
            }
        }
        return R.ok();
    }

    /**
     * 根据id删除分类
     *
     * @param productGroupId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteGroupById(Integer productGroupId) {
        //删除对应分类下的所有产品
        productService.remove(Wrappers.<ProductEntity>query().lambda()
                .eq(ProductEntity::getGroupId,productGroupId));

        //删除分类与部门关系
        productGroupDepartmentService.remove(Wrappers.<ProductGroupDepartmentEntity>query().lambda()
                .eq(ProductGroupDepartmentEntity::getGroupId,productGroupId));

        return baseMapper.deleteById(productGroupId) == 1;
    }

    /**
     * 根据id获取分类
     * @param id
     * @return
     */
    @Override
    public R getProductGroupByDept(Integer id) {
        List<ProductGroupDepartmentEntity> entities = productGroupDepartmentService.getBaseMapper().selectList(Wrappers.<ProductGroupDepartmentEntity>lambdaQuery()
                .eq(ProductGroupDepartmentEntity::getDeptId, id));
        Integer[] list = new Integer[entities.size()];
        int i = 0;
        List<ProductGroupVO> groupVOS = new LinkedList<>();
        for (ProductGroupDepartmentEntity p:entities) {
            list[i] = p.getGroupId();
            i++;
        }
        if (entities.isEmpty()){
            List<ProductGroupEntity> list1 = list(Wrappers.<ProductGroupEntity>lambdaQuery().eq(ProductGroupEntity::getVisibleRange, 1).eq(ProductGroupEntity::getCorpId,CorpContextHolder.getCorpId()));
            log.error("全部部门可见列表 = " + list1);
            for (ProductGroupEntity entity : list1) {
                ProductGroupVO groupVO = new ProductGroupVO();
                BeanUtil.copyProperties(entity,groupVO);
                groupVOS.add(groupVO);
            }
            return R.ok(groupVOS);
        }
        List<ProductGroupEntity> productGroupEntityList = baseMapper.selectList(Wrappers.<ProductGroupEntity>lambdaQuery()
                .eq(ProductGroupEntity::getCorpId, CorpContextHolder.getCorpId())
                .eq(BaseEntity::getTenantId, TenantContextHolder.getTenantId())
                .in(ProductGroupEntity::getId, list));

        for (ProductGroupEntity p:productGroupEntityList) {
            p.setCorpId(CorpContextHolder.getCorpId());
            ProductGroupVO groupVO = new ProductGroupVO();
            if (Constant.VISIBLE_RANGE_2.equals(p.getVisibleRange())) {
                List<Integer> lists = new LinkedList<>();
                List<ProductGroupDepartmentEntity> entityList = productGroupDepartmentService.list(
                        Wrappers.<ProductGroupDepartmentEntity>lambdaQuery()
                                .eq(ProductGroupDepartmentEntity::getGroupId, p.getId()));
                for (ProductGroupDepartmentEntity s : entityList) {
//                    WorkDeptEntity byId = deptService.getById(s.getDeptId());
                    lists.add(s.getDeptId());
                }
                groupVO.setDeptList(lists);
            }
            BeanUtils.copyProperties(p,groupVO);
            groupVOS.add(groupVO);
        }
        List<ProductGroupEntity> list1 = list(Wrappers.<ProductGroupEntity>lambdaQuery().eq(ProductGroupEntity::getVisibleRange, 1).eq(ProductGroupEntity::getCorpId,CorpContextHolder.getCorpId()));
        log.error("全部部门可见列表 = " + list1);
        for (ProductGroupEntity entity : list1) {
            ProductGroupVO groupVO = new ProductGroupVO();
            BeanUtil.copyProperties(entity,groupVO);
            groupVOS.add(groupVO);
        }
        log.error("所有权限可见列表："+groupVOS);
        groupVOS.sort(Comparator.comparing(ProductGroupVO::getId));
        return R.ok(groupVOS);
    }

    /**
     *  获取分类列表
     * @return
     */
    @Override
    public R getGroupList(){
        List<ProductGroupEntity> entityList = this.list(Wrappers.<ProductGroupEntity>query().lambda()
                .eq(ProductGroupEntity::getCorpId, CorpContextHolder.getCorpId())
                .orderByAsc(ProductGroupEntity::getId));

        ArrayList<ProductGroupVO> productGroupVOList = new ArrayList<>();
        for (ProductGroupEntity productGroupEntity : entityList) {
            ProductGroupVO productGroupVO = new ProductGroupVO();
            productGroupVO.setId(productGroupEntity.getId());
            productGroupVO.setName(productGroupEntity.getName());
            productGroupVO.setVisibleRange(productGroupEntity.getVisibleRange());
            //根据分类id查中间表获取部门id集合
            List<ProductGroupDepartmentEntity> groupDepartmentEntityList = productGroupDepartmentService.list(Wrappers.<ProductGroupDepartmentEntity>lambdaQuery()
                    .eq(ProductGroupDepartmentEntity::getGroupId, productGroupEntity.getId()));
            List<Integer> deptIds = groupDepartmentEntityList.stream()
                    .map(ProductGroupDepartmentEntity::getDeptId)
                    .collect(Collectors.toList());

            productGroupVO.setDeptList(deptIds);
            productGroupVOList.add(productGroupVO);
        }
//        //追加精选
//        ProductGroupVO selectionGroupVO = new ProductGroupVO();
//        selectionGroupVO.setId(0);
//        selectionGroupVO.setName("精选");
//        selectionGroupVO.setVisibleRange(1);
//        productGroupVOList.add(selectionGroupVO);
        productGroupVOList.sort(Comparator.comparing(ProductGroupVO::getId));
        return R.ok(productGroupVOList);
    }

    /**
     * 侧边栏获取  产品分类
     * @return
     */
    @Override
    public R getSidebarGroupList(String wxUserId) {
        ArrayList<ProductGroupVO> productGroupVOList = new ArrayList<>();
        Integer corpId = CorpContextHolder.getCorpId();
        ProdEmployeeEntity one = prodEmployeeService.getOne(Wrappers.<ProdEmployeeEntity>lambdaQuery().eq(ProdEmployeeEntity::getEmployeeId, wxUserId).eq(ProdEmployeeEntity::getCorpId, corpId));
        if(one==null){
            throw new CheckedException("请先申请产品经理资质！");
        }else if(one.getState()==1){
             return R.ok(productGroupVOList);
        }else {
            //限制可展示分类数据：11-理财产品，12-热门基金，13-保险产品，16-私募产品
            Integer[] rangeIds = new Integer[] {11,12,13,16};
            List<Integer> myDeptIds = getAdminDeptId(wxUserId);
            List<Integer> myGroupIds = new ArrayList<>();
            if (myDeptIds.size() != 0) {
                myGroupIds = productGroupDepartmentService.listObjs(Wrappers.<ProductGroupDepartmentEntity>lambdaQuery()
                        .select(ProductGroupDepartmentEntity::getGroupId)
                        .in(ProductGroupDepartmentEntity::getGroupId,rangeIds)
                        .in(ProductGroupDepartmentEntity::getDeptId, myDeptIds))
                        .stream().map(m -> Integer.parseInt(m.toString())).collect(Collectors.toList());
            }
            if (myGroupIds.size() == 0) myGroupIds.add(null);
            List<ProductGroupEntity> entityList = this.list(Wrappers.<ProductGroupEntity>query().lambda()
                    .eq(ProductGroupEntity::getCorpId, CorpContextHolder.getCorpId())
                    .in(ProductGroupEntity::getId, myGroupIds)
                    .or(wrapper1 -> wrapper1.in(ProductGroupEntity::getId,rangeIds).eq(ProductGroupEntity::getCorpId, corpId).eq(ProductGroupEntity::getVisibleRange, 1)));

            for (ProductGroupEntity productGroupEntity : entityList) {
                ProductGroupVO productGroupVO = new ProductGroupVO();
                productGroupVO.setId(productGroupEntity.getId());
                productGroupVO.setName(productGroupEntity.getName());
                productGroupVO.setVisibleRange(productGroupEntity.getVisibleRange());
                //根据分类id查中间表获取部门id集合
                List<ProductGroupDepartmentEntity> groupDepartmentEntityList = productGroupDepartmentService.list(Wrappers.<ProductGroupDepartmentEntity>lambdaQuery()
                        .eq(ProductGroupDepartmentEntity::getGroupId, productGroupEntity.getId()));
                List<Integer> deptIds = groupDepartmentEntityList.stream()
                        .map(ProductGroupDepartmentEntity::getDeptId)
                        .distinct().collect(Collectors.toList());
                ProdEmployeeGroupEntity groupEntity = prodEmployeeGroupService.getOne(Wrappers.<ProdEmployeeGroupEntity>lambdaQuery()
                        .eq(ProdEmployeeGroupEntity::getCorpId, corpId)
                        .eq(ProdEmployeeGroupEntity::getProdGroupId, productGroupEntity.getId())
                        .eq(ProdEmployeeGroupEntity::getEmployeeId, wxUserId));
                if(groupEntity!=null){
                    productGroupVO.setName(groupEntity.getProdGroupName());
                    productGroupVO.setProdGroupImg(groupEntity.getProdGroupImg());
                }
                productGroupVO.setDeptList(deptIds);
                productGroupVOList.add(productGroupVO);
            }
            productGroupVOList.sort(Comparator.comparing(ProductGroupVO::getId));
            String range = one.getProdRange();
            ArrayList<ProductGroupVO> vos = new ArrayList<>();
            if(StrUtil.isNotBlank(range)){
                String[] split = range.split(",");
                for (String s : split) {
                    List<ProductGroupVO> vo = productGroupVOList.stream().filter(o ->s.equals(o.getId().toString())).collect(Collectors.toList());
                    vos.addAll(vo);
                }
            }
            return R.ok(vos);
        }
    }

    public List<Integer> getAdminDeptId(String wxUserId) {
        Integer corpId = CorpContextHolder.getCorpId();
        Integer employeeId = workEmployeeService.getObj(Wrappers.<WorkEmployeeEntity>query().select("id").eq("wx_user_id", wxUserId).eq("corp_id", corpId), o -> Integer.parseInt(o.toString()));
        // 查询员工所属的部门 id 列表
        List<Integer> idList = workEmployeeDepartmentService.lambdaQuery()
                .select(WorkEmployeeDepartmentEntity::getDepartmentId)
                .eq(WorkEmployeeDepartmentEntity::getEmployeeId, employeeId)
                .list()
                .stream()
                .map(WorkEmployeeDepartmentEntity::getDepartmentId)
                .collect(Collectors.toList());

        // 查询部门及子部门 id 列表
        ArrayList<Integer> childs = new ArrayList<>();
        idList.forEach(f -> {
            List<Integer> allChilds = workDeptService.getAllChilds(f);
            childs.addAll(allChilds);
        });
        List<Integer> myList = childs.stream().distinct().collect(Collectors.toList());
        // 部门及子部门 id 列表
        return myList;
    }

}
